﻿using System.Xml.Linq;
using BattleFury.Lib.Extensions;
using BattleFury.Lib.Input;
using Microsoft.Xna.Framework;

namespace BattleFury.Lib.Controls
{
	public class Slider
		: Control
	{
		public static string PartSlide = "Slider";
		public static string PartSlideHighlighted = "SliderHighlighted";
		public static string PartSlideClicked = "SliderClicked";
		public static string PartGrooveLeft = "SliderBarLeft";
		public static string PartGrooveCenter = "SliderBarCenter";
		public static string PartGrooveRight = "SliderBarRight";

		private Part _slidePart;
		private Part _slideHighlightedPart;
		private Part _slideClickedPart;
		private Part _leftGroovePart;
		private Part _centerGroovePart;
		private Part _rightGroovePart;

		private string _slideState = "Normal";
		private bool _isDragging = false;

		public double Value { get; set; }
		public double Minimum { get; set; }
		public double Maximum { get; set; }
		public Color GrooveColor { get; set; }
		public Color SlideColor { get; set; }

		public override void Deserialize(XElement element, object callingObject)
		{
			base.Deserialize(element, callingObject);

			Minimum = element.GetDouble("Minimum", 0);
			Maximum = element.GetDouble("Maximum", 100);
			Value = element.GetDouble("Value", Minimum);
			GrooveColor = element.GetColor("GrooveColor", Color.White);
			SlideColor = element.GetColor("SlideColor", Color.White);
			Value = 50;
		}

		public override void Update(GameTime gameTime)
		{
			if (_slidePart == null)
			{
				_leftGroovePart = Skin[PartGrooveLeft];
				_centerGroovePart = Skin[PartGrooveCenter];
				_rightGroovePart = Skin[PartGrooveRight];
				_slidePart = Skin[PartSlide];
				_slideHighlightedPart = Skin[PartSlideHighlighted];
				_slideClickedPart = Skin[PartSlideClicked];
			}

			var sliderValue = (Value / (Maximum - Minimum)) * Size.X;
			var slideRect = new Rectangle((int)(Position.X + sliderValue - (_slidePart.Width / 2)), (int)Position.Y, _slidePart.Width, _slidePart.Height);
			var input = RenderEngine.Get().Input;
			_slideState = "Normal";
			_isDragging = false;
			if (input.Mouse.CurrentBounds.Intersects(slideRect))
			{
				_slideState = "Highlighted";
				if (input.Mouse.IsMouseButtonHeld(MouseButtons.Left))
				{
					_slideState = "Clicked";
					_isDragging = true;
				}
				if (_isDragging)
				{
					var startX = Position.X;
					var endX = Position.X + Size.X;
					var vX = ((input.Mouse.CurrentLocation.X - startX) / (endX - startX)) * (Maximum - Minimum);
					Value = vX;
					if (Value < Minimum) Value = Minimum;
					if (Value > Maximum) Value = Maximum;
				}
			}
		}

		public override void Draw(GameTime gameTime)
		{
			SpriteBatch.Draw(Texture, Position, _leftGroovePart.SourceBounds, GrooveColor);

			var innerWidth = (Size.X - _leftGroovePart.Width - _rightGroovePart.Width);
			for (var i = 0; i < innerWidth; i += _centerGroovePart.Width)
			{
				SpriteBatch.Draw(Texture, Position + new Vector2(_leftGroovePart.Width + i, 0f), _centerGroovePart.SourceBounds, GrooveColor);
			}

			SpriteBatch.Draw(Texture, Position + new Vector2(innerWidth + _leftGroovePart.Width, 0f), _rightGroovePart.SourceBounds, GrooveColor);

			var slidePart = _slidePart;
			if (_slideState == "Highlighted") slidePart = _slideHighlightedPart;
			if (_slideState == "Clicked") slidePart = _slideClickedPart;

			var sliderValue = (Value / (Maximum - Minimum)) * Size.X;
			var slideRect = new Rectangle((int)(Position.X + sliderValue - (slidePart.Width / 2)), (int)Position.Y, slidePart.Width, slidePart.Height);
			SpriteBatch.Draw(Texture, slideRect, slidePart.SourceBounds, SlideColor);
		}
	}
}